﻿using System;
using System.Collections;

namespace Jerkymon.Dates
{
    public class Utility
    {
		#region Static Methods (23)
		public static int AgeCalculate(System.DateTime dateOfBirth)
        {
            int dayBirth;
            int monthBirth;
            int yearBirth;

            try
            {
                //Constructor
                dayBirth = dateOfBirth.Day;
                monthBirth = dateOfBirth.Month;
                yearBirth = dateOfBirth.Year;

                DateTime birthDayThisYear = new DateTime(DateTime.Today.Year, monthBirth, dayBirth);
                int years = DateTime.Today.Year - yearBirth;
                int months = DateTime.Today.Month - monthBirth;
                int days = DateTime.Today.Day - dayBirth;

                if (birthDayThisYear > DateTime.Today) //you've not yet celebrated your birthday this year
                {
                    years -= 1;
                    months += 12;
                }
                if (birthDayThisYear.Day > DateTime.Today.Day)
                {
                    months -= 1;
                    DateTime dt = new DateTime(birthDayThisYear.Year, DateTime.Today.Month - 1, birthDayThisYear.Day);
                    TimeSpan ts = DateTime.Today - dt;
                    days = ts.Days;
                }
                return years;
            }
            catch (Exception) // Swallow Exception
            {
                // throw your exception here 
                return 0;
            }

        }

		public static string AppendData(int digits, string variables, string data)
        {
            string sdata = "";

            if (data.Length < digits)
            {
                int looping = digits - data.Length;

                for (int x = 0; x != looping; x++)
                {
                    sdata += variables;
                }

                sdata += data;
            }
            else
            {
                sdata = data;
            }

            return sdata;
        }

		public static long DateDiff(DateInterval interval, DateTime date1, DateTime date2)
        {

            TimeSpan ts = ts = date2 - date1;

            switch (interval)
            {
                case DateInterval.Year:
                    return date2.Year - date1.Year;
                case DateInterval.Month:
                    return (date2.Month - date1.Month) + (12 * (date2.Year - date1.Year));
                case DateInterval.Weekday:
                    return Jerkymon.Numeric.Utility.Fix(ts.TotalDays) / 7;
                case DateInterval.Day:
                    return Jerkymon.Numeric.Utility.Fix(ts.TotalDays);
                case DateInterval.Hour:
                    return Jerkymon.Numeric.Utility.Fix(ts.TotalHours);
                case DateInterval.Minute:
                    return Jerkymon.Numeric.Utility.Fix(ts.TotalMinutes);
                default:
                    return Jerkymon.Numeric.Utility.Fix(ts.TotalSeconds);
            }
        }

		public static string DateFormat(System.DateTime dateTostring)
        {
            DateTime dt = DateTime.Now;
            string dts, dtn, dty;
            dts = DateToString(dateTostring, "MMDDYYYY");
            dtn = DateToString(dt, "MMDDYYYY");
            dty = DateToString(dt.AddDays(-1), "MMDDYYYY");
            string dtFormat = string.Empty;
            if (dts == dtn)
            {
                long h = 0, m = 0;
                h = Jerkymon.Dates.Utility.DateDiff(Jerkymon.DateInterval.Hour, dateTostring, dt);
                m = Jerkymon.Dates.Utility.DateDiff(Jerkymon.DateInterval.Minute, dateTostring, dt);

                if (h > 0)
                {
                    if (h == 1)
                        dtFormat += h.ToString() + " hour, ";
                    else
                        dtFormat += h.ToString() + " hours, ";

                    dtFormat += Convert.ToString(m % 60) + " minutes ago.";
                }
                else
                {
                    if (m > 1)
                        dtFormat += m.ToString() + " minutes ago.";
                    else
                        dtFormat += m.ToString() + " minute ago.";
                }

                return "Today, " + dtFormat;
            }
            else if (dts == dty)
            {
                return "Yesterday, " + dateTostring.ToString("t");
            }
            else
            {

                return dateTostring.ToString("D");
            }
        }

		public static string DateToString(System.DateTime dateTostring)
        {
            return DateToString(dateTostring, "MMDDYYYYHHMMSS");
        }

		public static string DateToString(System.DateTime dateTostring, string format)
        {
            format = format.ToUpper();
            string datetostring = "";
            int days;
            int months;
            int years;
            int hours;
            int minutes;
            int seconds;

            //Constructor
            days = dateTostring.Day;
            months = dateTostring.Month;
            years = dateTostring.Year;
            hours = dateTostring.Hour;
            minutes = dateTostring.Minute;
            seconds = dateTostring.Second;

            switch (format)
            {
                case "MMDDYYYYHHMMSS":
                    datetostring += AppendData(2, "0", months.ToString());
                    datetostring += AppendData(2, "0", days.ToString());
                    datetostring += AppendData(4, "0", years.ToString());
                    datetostring += AppendData(2, "0", hours.ToString());
                    datetostring += AppendData(2, "0", minutes.ToString());
                    datetostring += AppendData(2, "0", seconds.ToString());
                    break;
                case "MM.DD.YYYY":
                    datetostring += AppendData(2, "0", months.ToString());
                    datetostring += ".";
                    datetostring += AppendData(2, "0", days.ToString());
                    datetostring += ".";
                    datetostring += AppendData(4, "0", years.ToString());
                    break;
                case "MM-DD-YYYY":
                    datetostring += AppendData(2, "0", months.ToString());
                    datetostring += "-";
                    datetostring += AppendData(2, "0", days.ToString());
                    datetostring += "-";
                    datetostring += AppendData(4, "0", years.ToString());
                    break;
                case "MM/DD/YYYY":
                    datetostring += AppendData(2, "0", months.ToString());
                    datetostring += "/";
                    datetostring += AppendData(2, "0", days.ToString());
                    datetostring += "/";
                    datetostring += AppendData(4, "0", years.ToString());
                    break;
                case "MM/DD/YY":
                    datetostring += AppendData(2, "0", months.ToString());
                    datetostring += "/";
                    datetostring += AppendData(2, "0", days.ToString());
                    datetostring += "/";
                    datetostring += AppendData(2, "0", years.ToString());
                    break;
                case "MM-DD-YY":
                    datetostring += AppendData(2, "0", months.ToString());
                    datetostring += "-";
                    datetostring += AppendData(2, "0", days.ToString());
                    datetostring += "-";
                    datetostring += AppendData(2, "0", years.ToString());
                    break;
                case "MMDDYYYYHHMM":
                    datetostring += AppendData(2, "0", months.ToString());
                    datetostring += AppendData(2, "0", days.ToString());
                    datetostring += AppendData(4, "0", years.ToString());
                    datetostring += AppendData(2, "0", hours.ToString());
                    datetostring += AppendData(2, "0", minutes.ToString());
                    break;
                case "YYYYMMDDHHMMSS":
                    datetostring += AppendData(4, "0", years.ToString());
                    datetostring += AppendData(2, "0", months.ToString());
                    datetostring += AppendData(2, "0", days.ToString());
                    datetostring += AppendData(2, "0", hours.ToString());
                    datetostring += AppendData(2, "0", minutes.ToString());
                    datetostring += AppendData(2, "0", seconds.ToString());
                    break;
                case "MMDDYYYY":
                    datetostring += AppendData(2, "0", months.ToString());
                    datetostring += AppendData(2, "0", days.ToString());
                    datetostring += AppendData(4, "0", years.ToString());
                    break;
                case "YYYYMMDD":
                    datetostring += AppendData(4, "0", years.ToString());
                    datetostring += AppendData(2, "0", months.ToString());
                    datetostring += AppendData(2, "0", days.ToString());
                    break;
                case "YYMMDD":
                    datetostring += AppendData(2, "0", years.ToString());
                    datetostring += AppendData(2, "0", months.ToString());
                    datetostring += AppendData(2, "0", days.ToString());
                    break;
                case "HHMMSS":
                    datetostring += AppendData(2, "0", hours.ToString());
                    datetostring += AppendData(2, "0", minutes.ToString());
                    datetostring += AppendData(2, "0", seconds.ToString());
                    break;
                case "HHMM":
                    datetostring += AppendData(2, "0", hours.ToString());
                    datetostring += AppendData(2, "0", minutes.ToString());
                    datetostring += AppendData(2, "0", seconds.ToString());
                    break;
                default:
                    datetostring += AppendData(2, "0", months.ToString());
                    datetostring += AppendData(2, "0", days.ToString());
                    datetostring += AppendData(4, "0", years.ToString());
                    datetostring += AppendData(2, "0", hours.ToString());
                    datetostring += AppendData(2, "0", minutes.ToString());
                    datetostring += AppendData(2, "0", seconds.ToString());
                    break;
            }

            //if (format == "MMDDYYYYHHMMSS")
            //{
            //    datetostring += AppendData(2, "0", months.ToString());
            //    datetostring += AppendData(2, "0", days.ToString());
            //    datetostring += AppendData(4, "0", years.ToString());
            //    datetostring += AppendData(2, "0", hours.ToString());
            //    datetostring += AppendData(2, "0", minutes.ToString());
            //    datetostring += AppendData(2, "0", seconds.ToString());
            //}
            //else if (format == "MM.DD.YYYY")
            //{
            //    datetostring += AppendData(2, "0", months.ToString());
            //    datetostring += ".";
            //    datetostring += AppendData(2, "0", days.ToString());
            //    datetostring += ".";
            //    datetostring += AppendData(4, "0", years.ToString());
            //}
            //else if (format == "MM/DD/YYYY")
            //{
            //    datetostring += AppendData(2, "0", months.ToString());
            //    datetostring += ".";
            //    datetostring += AppendData(2, "0", days.ToString());
            //    datetostring += ".";
            //    datetostring += AppendData(4, "0", years.ToString());
            //}
            //else if (format == "MMDDYYYYHHMM")
            //{
            //    datetostring += AppendData(2, "0", months.ToString());
            //    datetostring += AppendData(2, "0", days.ToString());
            //    datetostring += AppendData(4, "0", years.ToString());
            //    datetostring += AppendData(2, "0", hours.ToString());
            //    datetostring += AppendData(2, "0", minutes.ToString());
            //}
            //else if (format == "YYYYMMDDHHMMSS")
            //{
            //    datetostring += AppendData(4, "0", years.ToString());
            //    datetostring += AppendData(2, "0", months.ToString());
            //    datetostring += AppendData(2, "0", days.ToString());
            //    datetostring += AppendData(2, "0", hours.ToString());
            //    datetostring += AppendData(2, "0", minutes.ToString());
            //    datetostring += AppendData(2, "0", seconds.ToString());
            //}
            //else if (format == "MMDDYYYY")
            //{
            //    datetostring += AppendData(2, "0", months.ToString());
            //    datetostring += AppendData(2, "0", days.ToString());
            //    datetostring += AppendData(4, "0", years.ToString());
            //}
           
            //else if (format == "YYYYMMDD")
            //{
            //    datetostring += AppendData(4, "0", years.ToString());
            //    datetostring += AppendData(2, "0", months.ToString());
            //    datetostring += AppendData(2, "0", days.ToString());
            //}
            //else if (format == "YYMMDD")
            //{
            //    datetostring += AppendData(4, "0", years.ToString());
            //    datetostring += AppendData(2, "0", months.ToString());
            //    datetostring += AppendData(2, "0", days.ToString());
            //}
            //else if (format == "HHMMSS")
            //{
            //    datetostring += AppendData(2, "0", hours.ToString());
            //    datetostring += AppendData(2, "0", minutes.ToString());
            //    datetostring += AppendData(2, "0", seconds.ToString());
            //}

            //else if (format == "HHMM")
            //{
            //    datetostring += AppendData(2, "0", hours.ToString());
            //    datetostring += AppendData(2, "0", minutes.ToString());
            //    datetostring += AppendData(2, "0", seconds.ToString());
            //}
            //else
            //{
            //    datetostring += AppendData(2, "0", months.ToString());
            //    datetostring += AppendData(2, "0", days.ToString());
            //    datetostring += AppendData(4, "0", years.ToString());
            //    datetostring += AppendData(2, "0", hours.ToString());
            //    datetostring += AppendData(2, "0", minutes.ToString());
            //    datetostring += AppendData(2, "0", seconds.ToString());
            //}

            return datetostring;

        }

		public static string DayNameFromDate(DateTime dt, Boolean bShort)
        {
            if (bShort)
            {
                //	Return a short day name.
                return dt.DayOfWeek.ToString().Substring(0, 3);
            }
            else
            {
                //	Return full day name.
                return dt.DayOfWeek.ToString();
            }
        }

		public static string DayNameFromDayNumber(Int32 DayOfWeek)
        {
            return DayNameFromDayNumber(DayOfWeek, true);
        }

		public static string DayNameFromDayNumber(Int32 DayOfWeek, Boolean bShort)
        {
            DateTime dt = DateTime.Today;

            while (dt.DayOfWeek.ToString() != "Sunday")
                dt = dt.AddDays(-1);

            return DayNameFromDate(dt.AddDays(DayOfWeek - 1), bShort);
        }

		public static DateTime FirstDayOfMonth(DateTime dt)
        {
            while (dt.Day > 1)
                dt = dt.AddDays(-1);

            return dt;
        }

		public static DateTime FirstDayOfWeek(DateTime dt)
        {
            while (dt.DayOfWeek.ToString() != "Monday")
                dt = dt.AddDays(-1);

            return dt;
        }

		public static string GetAge(string strBDay)
        {
            // current date.
            string strCDate = DateTime.Now.ToShortDateString();
            // get year born & current year.
            int yearborn = Convert.ToDateTime(strBDay).Year;
            int yearnow = Convert.ToDateTime(strCDate).Year;
            int totalyears = yearnow - yearborn;
            // split bday up.
            int strBDay_day = Convert.ToDateTime(strBDay).Day;
            int strBDay_month = Convert.ToDateTime(strBDay).Month;
            // get how many days since or till the bday this year.
            TimeSpan hadbday = new TimeSpan();
            string thisyearbday = Convert.ToString(strBDay_day + "." + strBDay_month + "." + yearnow);
            hadbday = Convert.ToDateTime(strBDay) - Convert.ToDateTime(thisyearbday);
            // get age.
            int age = (totalyears - 1);
            if (hadbday.TotalDays >= 0)
            {
                age++;
            }
            // return result.
            return Convert.ToString(age);
        }

		public static ArrayList GetWeekDateRange(System.DateTime d)
        {
            ArrayList list = new ArrayList();
            System.DateTime stDate, endDate;

            double offset = 0;

            if (d.DayOfWeek == DayOfWeek.Sunday)
            {
                offset = -6;
            }
            else if (d.DayOfWeek == DayOfWeek.Monday)
            {
                offset = 0;
            }
            else if (d.DayOfWeek == DayOfWeek.Tuesday)
            {
                offset = -1;
            }
            else if (d.DayOfWeek == DayOfWeek.Wednesday)
            {
                offset = -2;
            }
            else if (d.DayOfWeek == DayOfWeek.Thursday)
            {
                offset = -3;
            }
            else if (d.DayOfWeek == DayOfWeek.Friday)
            {
                offset = -4;
            }
            else if (d.DayOfWeek == DayOfWeek.Saturday)
            {
                offset = -5;
            }

            stDate = System.DateTime.Today.AddDays(offset);
            endDate = System.DateTime.Today.AddDays(7 + offset - 1);	 // -1 so that from monday to sunday only not monday to monday next week

            list.Add(stDate); // index[0] is the begin of date range
            list.Add(endDate); // index[1] is the end of date range

            return list;

        }

		public static int GetWeekNumber(System.DateTime inDate)
        {
            int dayOfYear;
            int wkNumber;
            int compensation = 0;
            string oneDate;
            System.DateTime firstDayDate;
            dayOfYear = inDate.DayOfYear;
            oneDate = "1/1/" + inDate.Year.ToString();
            firstDayDate = DateTime.Parse(oneDate);
            if (firstDayDate.DayOfWeek == DayOfWeek.Sunday)
            {
                compensation = 0;
            }
            else if (firstDayDate.DayOfWeek == DayOfWeek.Monday)
            {
                compensation = 6;
            }
            else if (firstDayDate.DayOfWeek == DayOfWeek.Tuesday)
            {
                compensation = 5;
            }
            else if (firstDayDate.DayOfWeek == DayOfWeek.Wednesday)
            {
                compensation = 4;
            }
            else if (firstDayDate.DayOfWeek == DayOfWeek.Thursday)
            {
                compensation = 3;
            }
            else if (firstDayDate.DayOfWeek == DayOfWeek.Friday)
            {
                compensation = 2;
            }
            else if (firstDayDate.DayOfWeek == DayOfWeek.Saturday)
            {
                compensation = 1;
            }
            dayOfYear = dayOfYear - compensation;
            if (dayOfYear % 7 == 0)
            {
                wkNumber = dayOfYear / 7;
            }
            else
            {
                wkNumber = (dayOfYear / 7) + 1;
            }
            return wkNumber;
        }

		public static string HhMmSs(DateTime dt)
        {
            string RetVal = string.Format("{0:HH}{0:mm}{0:ss}", dt);

            return RetVal;
        }

		///////////////////////////////////////////////////////////////////////
        public static string HowLongAgo(TimeSpan ts)
        {

            if (ts.Days > 0)
            {
                if (ts.Days == 1)
                {
                    if (ts.Hours > 2)
                    {
                        return "1 day and " + ts.Hours + " hours ago";
                    }
                    else
                    {
                        return "1 day ago";
                    }
                }
                else
                {
                    return ts.Days + " days ago";
                }
            }
            else if (ts.Hours > 0)
            {
                if (ts.Hours == 1)
                {
                    if (ts.Minutes > 5)
                    {
                        return "1 hour and " + ts.Minutes + " minutes ago";
                    }
                    else
                    {
                        return "1 hour ago";
                    }
                }
                else
                {
                    return ts.Hours + " hours ago";
                }
            }
            else if (ts.Minutes > 0)
            {
                if (ts.Minutes == 1)
                {
                    return "1 minute ago";
                }
                else
                {
                    return ts.Minutes + " minutes ago";
                }
            }
            else
            {
                return ts.Seconds + " seconds ago";
            }

        }

		public static string HowLongAgo(int seconds)
        {
            //DateTime.Now.Second
            return HowLongAgo(new TimeSpan(0, 0, seconds));
        }

		public static bool IfValidDate(DateTime dt)
        {
            if ((dt > dt.MinValue()) && (dt < dt.MaxValue()))
                return true;
            else
                return false;
        }

        /// <summary>
        /// Determine if Date String is an actual date
        /// Date format = MM/DD/YYYY
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        public static bool IfValidDate(string date)
        {

            DateTime temp;
            if (DateTime.TryParse(date, out temp))
                return true;
            else
                return false;

        }

		public static DateTime LastDayOfMonth(DateTime dt)
        {
            Int32 MonthNo = dt.Month;

            while (dt.Month == MonthNo)
                dt = dt.AddDays(1);

            dt = dt.AddDays(-1);
            return dt;
        }

		public static DateTime LastDayOfWeek(DateTime dt)
        {
            while (dt.DayOfWeek.ToString() != "Sunday")
                dt = dt.AddDays(1);

            return dt;
        }

		public static string MonthNameFromNumber(Int32 MonthNo)
        {
            return MonthNameFromNumber(MonthNo, true);
        }

		public static string MonthNameFromNumber(Int32 MonthNo, Boolean bShort)
        {
            DateTime dt = DateTime.Parse("1 Jan 2000");

            while (MonthNo > 1)
            {
                dt = dt.AddMonths(1);
                MonthNo--;
            }

            if (bShort)
                return dt.ToString("MMMM").Substring(1, 3);
            else
                return dt.ToString("MMMM");
        }

		public static string ShowShortDate(DateTime dt)
        {
            string RetVal = string.Format("{0:dd} {0:MMM} {0:yy}", dt);

            return RetVal;
        }
		#endregion
    }

}
